package com.qingcloud.adminbackend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qingcloud.adminbackend.entity.domain.SysDomain;
import com.qingcloud.adminbackend.entity.equipment.EquipmentBaseDataDTO;
import com.qingcloud.adminbackend.entity.equipment.EquipmentNewBaseDataDTO;
import com.qingcloud.adminbackend.entity.equipment.EquipmentWeatherDataDTO;
import com.qingcloud.adminbackend.entity.monitordata.MonitorDataBO;
import com.qingcloud.adminbackend.entity.monitordata.MonitorDataDTO;
import com.qingcloud.adminbackend.entity.open.OpenEquipmentDataDTO;
import com.qingcloud.adminbackend.entity.sysstation.SysStationMoDTO;
import com.qingcloud.adminbackend.entity.weatherdata.WeatherBO;
import com.qingcloud.adminbackend.entity.weatherdata.WeatherDTO;
import com.qingcloud.adminbackend.entity.weatherdata.WeatherExportBO;
import com.qingcloud.adminbackend.mapper.SysDomainMapper;
import com.qingcloud.adminbackend.mapper.SysEquipmentMapper;
import com.qingcloud.adminbackend.mapper.SysStationGroupMapper;
import com.qingcloud.adminbackend.service.IWeatherDataService;
import com.qingcloud.adminbackend.utils.OKHttpUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WeatherDataServiceImpl implements IWeatherDataService {

    @Resource
    private SysEquipmentMapper sysEquipmentMapper;
    @Resource
    private SysStationGroupMapper sysStationGroupMapper;
    @Resource
    private SysDomainMapper sysDomainMapper;
    @Resource
    private BaseServiceImpl baseService;

    private static final Integer PROID = 1;
    private static final Integer CITYID = 2;
    private static final Integer DISTID = 3;
    @Value("${healthy.data-url}")
    private String crawlerUrl;

    @Override
    public IPage<WeatherDTO> getWeatherData(WeatherBO weatherBO, List<String> equipmentIds) {
        List<SysDomain> proList = sysDomainMapper.getAllDomainDTOById(PROID);
        List<SysDomain> cityList = sysDomainMapper.getAllDomainDTOById(CITYID);
        List<SysDomain> distList = sysDomainMapper.getAllDomainDTOById(DISTID);
        List<WeatherDTO> records = sysEquipmentMapper.getWeatherData(weatherBO, equipmentIds);
        List<SysStationMoDTO> stationMos = sysStationGroupMapper.findStationMo();
        Page<WeatherDTO> page = new Page<>(weatherBO.getCurrentPage(), weatherBO.getPerPage());
        List<String> ids = new ArrayList<>();
        Map<String, WeatherDTO> weatherDTOMap = new HashMap<>();
        records.stream().forEach(it -> {
            if (!StringUtils.isEmpty(it.getMoId())) {
                splitString(it, stationMos);
            }
            ids.add(it.getEquipmentId());
            weatherDTOMap.put(it.getEquipmentId(), it);
            domainNameString(it, proList, cityList, distList);
        });
        JSONObject param = new JSONObject();
        param.put("dateType", weatherBO.getStationQueryType());
        param.put("endTime", weatherBO.getEndDate());
        param.put("equipmentIdList", ids);
        param.put("startTime", weatherBO.getStartDate());
        param.put("length", weatherBO.getPerPage());
        param.put("page", weatherBO.getCurrentPage() == 0 ? 0 : weatherBO.getCurrentPage() - 1);
        httpPostJSON(param, weatherDTOMap, page);
        return page;
    }

    public List<WeatherDTO> httpPostJSON(JSONObject param, Map<String, WeatherDTO> weatherDTOMap, Page<WeatherDTO> page) {
        //发起请求
        String postDay = OKHttpUtil.httpPost(crawlerUrl+"edata/pagev2", param.toJSONString());
        //结束返回参数
        Map<String, Object> resultMap = (Map<String, Object>) JSONObject.parse(postDay);
        List<WeatherDTO> weatherDTOS = new ArrayList<>();
        if (postDay.contains("recordsTotal")) {
            String total = resultMap.get("recordsTotal") == null ? "0" : String.valueOf(resultMap.get("recordsTotal"));
            page.setTotal(Long.valueOf(total));
            List<EquipmentWeatherDataDTO> baseDataDTOS = JSONObject.parseArray(String.valueOf(resultMap.get("data")), EquipmentWeatherDataDTO.class);
            baseDataDTOS.forEach(baseData -> {
//                baseData.setTem(baseData.getTemperature());
//                baseData.setTemOrig(baseData.getTemperatureOrig());
//                baseData.setHum(baseData.getHumidity());
//                baseData.setHumOrig(baseData.getHumidityOrig());
                WeatherDTO weatherDTO = weatherDTOMap.get(baseData.getEquipmentId());
                WeatherDTO dto = new WeatherDTO();
                dto.setEquipmentId(weatherDTO.getEquipmentId());
                dto.setStationName(weatherDTO.getStationName());
                dto.setStationId(weatherDTO.getStationId());
                dto.setStationDetails(weatherDTO.getStationDetails());
                dto.setDomainDetails(weatherDTO.getDomainDetails());
                dto.setMoDetails(weatherDTO.getMoDetails());
                dto.setMoAddress(weatherDTO.getMoAddress());
                dto.setLat(weatherDTO.getLat());
                dto.setLng(weatherDTO.getLng());
                dto.setMoId(weatherDTO.getMoId());
                dto.setWorkType(weatherDTO.getWorkType());
                dto.setDomainId(weatherDTO.getDomainId());
                dto.setTime(baseData.getRtcTime());
                dto.setBusinessType(weatherDTO.getBusinessType());
                dto.setEquipmentBaseDataDTO(baseData);
                weatherDTOS.add(dto);
            });
            page.setRecords(weatherDTOS);
        }
        return weatherDTOS;
    }

    @Override
    public List<EquipmentNewBaseDataDTO> getWeatherDataList(WeatherExportBO weatherBO, List<String> equipmentIds) {
        List<SysDomain> proList = sysDomainMapper.getAllDomainDTOById(PROID);
        List<SysDomain> cityList = sysDomainMapper.getAllDomainDTOById(CITYID);
        List<SysDomain> distList = sysDomainMapper.getAllDomainDTOById(DISTID);
        //监测因子内容描述map
        List<WeatherDTO> weatherData = sysEquipmentMapper.getWeatherDataList(weatherBO, equipmentIds);
        List<String> ids = new ArrayList<>();
        Map<String, WeatherDTO> weatherDTOMap = new HashMap<>();
        weatherData.stream().forEach(it -> {
            domainNameString(it, proList, cityList, distList);
            ids.add(it.getEquipmentId());
            weatherDTOMap.put(it.getEquipmentId(), it);
        });
        JSONObject param = new JSONObject();
        param.put("dateType", weatherBO.getStationQueryType());
        param.put("endTime", weatherBO.getEndDate());
        param.put("equipmentIdList", ids);
        param.put("startTime", weatherBO.getStartDate());
        param.put("length", 9999999);
        param.put("page", 0);
        //发起请求
        String postDay = OKHttpUtil.httpPost(crawlerUrl+"edata/pagev2", param.toJSONString());
        //结束返回参数
        Map<String, Object> resultMap = (Map<String, Object>) JSONObject.parse(postDay);
        List<EquipmentNewBaseDataDTO> weatherDTOS = new ArrayList<>();
        if (postDay.contains("recordsTotal")) {
            List<EquipmentWeatherDataDTO> baseDataDTOS = JSONObject.parseArray(String.valueOf(resultMap.get("data")), EquipmentWeatherDataDTO.class);
            baseDataDTOS.forEach(baseData -> {
                WeatherDTO weatherDTO = weatherDTOMap.get(baseData.getEquipmentId());
                EquipmentNewBaseDataDTO dto = new EquipmentNewBaseDataDTO();
                BeanUtil.copyProperties(baseData, dto);
                dto.setStationName(weatherDTO.getStationName());
                dto.setStationId(weatherDTO.getStationId());
                dto.setDomainDetails(weatherDTO.getDomainDetails());
                dto.setLat(weatherDTO.getLat());
                dto.setLng(weatherDTO.getLng());
                weatherDTOS.add(dto);
            });
            return weatherDTOS;
        }
        return null;
    }

    /**
     * 监测数据列表API
     *
     * @param monitorDataBO
     * @return
     */
    @Override
    public IPage<MonitorDataDTO> getMonitorData(MonitorDataBO monitorDataBO) {
        List<MonitorDataDTO> records = sysEquipmentMapper.getMonitorData(monitorDataBO);
        IPage<MonitorDataDTO> page = new Page<>(monitorDataBO.getCurrentPage(), monitorDataBO.getPerPage());
        List<String> ids = new ArrayList<>();
        Map<String, MonitorDataDTO> monitorDTOMap = new HashMap<>();
        records.stream().forEach(it -> {
            ids.add(it.getEquipmentId());
            monitorDTOMap.put(it.getEquipmentId(), it);
        });
        JSONObject param = new JSONObject();
        param.put("dateType", 1);
        param.put("endTime", monitorDataBO.getEndTime());
        param.put("equipmentIdList", ids);
        param.put("startTime", monitorDataBO.getStartTime());
        param.put("length", monitorDataBO.getPerPage());
        param.put("page", monitorDataBO.getCurrentPage() == 0 ? 0 : monitorDataBO.getCurrentPage() - 1);
        //发起请求
        String postDay = OKHttpUtil.httpPost(crawlerUrl+"edata/page", param.toJSONString());
        //结束返回参数
        Map<String, Object> resultMap = (Map<String, Object>) JSONObject.parse(postDay);
        List<MonitorDataDTO> weatherDTOS = new ArrayList<>();
        if (postDay.contains("recordsTotal")) {
            String total = resultMap.get("recordsTotal") == null ? "0" : String.valueOf(resultMap.get("recordsTotal"));
            page.setTotal(Long.valueOf(total));
            List<EquipmentBaseDataDTO> baseDataDTOS = JSONObject.parseArray(String.valueOf(resultMap.get("data")), EquipmentBaseDataDTO.class);
            baseDataDTOS.forEach(baseData -> {
                MonitorDataDTO monitorDataDTO = monitorDTOMap.get(baseData.getEquipmentId());
                MonitorDataDTO dto = new MonitorDataDTO();
                dto.setEquipmentId(monitorDataDTO.getEquipmentId());
                dto.setLat(monitorDataDTO.getLat());
                dto.setLng(monitorDataDTO.getLng());
                dto.setRtcTime(baseData.getRtcTime());
                dto.setEquipmentBaseDataDTO(baseData);
                weatherDTOS.add(dto);
            });
            page.setRecords(weatherDTOS);
        }
        return page;
    }

    @Override
    public List<String> findMonitorDataList() {
        List<MonitorDataDTO> monitorData = sysEquipmentMapper.getMonitorData(new MonitorDataBO());
        List<String> modelDTOS = new ArrayList<>();
        if (monitorData != null) {
            monitorData.forEach(it -> {
                modelDTOS.add(it.getEquipmentId());
            });
        }
        return modelDTOS;
    }

    /**
     * 功能描述: 组装空间名称
     *
     * @param:
     * @return:
     * @auther: Destiny
     * @date: 2019/4/23 16:51
     */
    private void splitString(WeatherDTO weatherDTO, List<SysStationMoDTO> stationMos) {
        if ("2".equals(weatherDTO.getWorkType())) {
            List<String> list1 = new ArrayList<>();
            int z = 5;
            int num = (weatherDTO.getMoId().length() / 5) - 1;
            if (num > 0) {
                for (int i = 0; i < num; i++) {
                    list1.add(weatherDTO.getMoId().substring(0, weatherDTO.getMoId().length() - z));
                    z = z + 5;
                }
            }
            list1.add(weatherDTO.getMoId());
            String capation = "";
            for (SysStationMoDTO it : stationMos) {
                if (list1.contains(it.getId())) {
                    capation = capation.concat(it.getCapation()).concat("-");
                }
            }
            if (StrUtil.isNotBlank(capation)) {
                capation = capation.substring(0, capation.length() - 1);
            }
            weatherDTO.setMoDetails(capation);
        }
    }

    public void domainNameString(WeatherDTO weatherDTO, List<SysDomain> proList, List<SysDomain> cityList, List<SysDomain> distList) {
        String domainName = "";
        if (StrUtil.isNotBlank(weatherDTO.getStationId())) {
            weatherDTO.setStationDetails(weatherDTO.getStationName().concat("[").concat(weatherDTO.getStationId()).concat("]"));
        }
        if (StrUtil.isNotBlank(weatherDTO.getDomainId())) {
            Integer domainId = Integer.valueOf(weatherDTO.getDomainId());
            Long cityId = null;
            for (SysDomain dist : distList) {
                if (dist.getId().equals(domainId)) {
                    cityId = dist.getParentId();
                    domainName = domainName.concat(dist.getDomainName());
                    break;
                }
            }
            if (cityId != null) {
                Long proid = null;
                for (SysDomain city : cityList) {
                    if (city.getId().equals(cityId)) {
                        proid = city.getParentId();
                        domainName = city.getDomainName().concat("/").concat(domainName);
                        break;
                    }
                }
                if (proid != null) {
                    for (SysDomain pro : proList) {
                        if (pro.getId().equals(proid)) {
                            domainName = pro.getDomainName().concat("/").concat(domainName);
                            break;
                        }
                    }
                }
            }
            weatherDTO.setStationDetails(weatherDTO.getStationDetails().concat(domainName));
            weatherDTO.setDomainDetails(domainName);
        }
    }

    /**
     * 查询设备数据
     *
     * @param equipmentIds 设备编号
     * @param startTime    开始时间
     * @param endTime      截至时间
     * @return 设备数据列表
     */
    @Override
    public List<OpenEquipmentDataDTO> getEquipmentData(List<String> equipmentIds, String startTime, String endTime) {
        JSONObject param = new JSONObject();
        param.put("dateType", 1);
        param.put("endTime", endTime);
        param.put("equipmentIdList", equipmentIds);
        param.put("startTime", startTime);
        //发起请求
        String postDay = OKHttpUtil.httpPost(crawlerUrl+"edata/page", param.toJSONString());
        //结束返回参数
        Map<String, Object> resultMap = (Map<String, Object>) JSONObject.parse(postDay);
        if (postDay.contains("recordsTotal")) {
            List<EquipmentBaseDataDTO> baseDataDTOS = JSONObject.parseArray(String.valueOf(resultMap.get("data")), EquipmentBaseDataDTO.class);
            return baseDataDTOS.stream().map(it -> {
                OpenEquipmentDataDTO dataDTO = new OpenEquipmentDataDTO();
                dataDTO.setEquipmentId(it.getEquipmentId());
                dataDTO.setPm25(it.getPm25());
                dataDTO.setCo2(it.getCo2());
                dataDTO.setAerosol(it.getVirus());
                dataDTO.setTemperature(it.getTemperature());
                dataDTO.setHumidity(it.getHumidity());
                dataDTO.setDataTime(it.getRtcTime());
                return dataDTO;
            }).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

}
